import {
  AfterContentInit,
  ChangeDetectionStrategy,
  ChangeDetectorRef,
  Component,
  Inject,
  InjectionToken,
  Injector,
  StaticProvider,
  ViewEncapsulation,
} from '@angular/core'
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog'

import { TemplateRef } from '@angular/core'
import { ComponentPortal, ComponentType, Portal, TemplatePortal } from '@angular/cdk/portal'

export const AD_CONFIRM_DATA = new InjectionToken<any>('AdConfirmData')
export const AD_CONFIRM_REF = new InjectionToken<any>('AdConfirmRef')

export type ConfirmType = 'success' | 'error' | 'warning'

export type ConfirmContent = string | TemplateRef<any> | ComponentType<any>
export interface ConfirmParams<T = any> {
  type?: ConfirmType
  isShowCancel?: boolean
  isShowConfirm?: boolean
  cancelText?: string
  confirmText?: string
  cancelIsReject?: boolean
  content?: ConfirmContent
  data?: T
}

@Component({
  selector: 'ad-confirm',
  templateUrl: './confirm.component.html',
  changeDetection: ChangeDetectionStrategy.OnPush,
  encapsulation: ViewEncapsulation.None,
  host: {
    class: 'ad-confirm',
  },
})
export class AdConfirmComponent implements AfterContentInit {
  portal: Portal<any>
  constructor(
    @Inject(MAT_DIALOG_DATA) public data: ConfirmParams,
    private injector: Injector,
    public dialogRef: MatDialogRef<AdConfirmComponent>,
    public cdr: ChangeDetectorRef
  ) {}
  ngAfterContentInit(): void {
    if (typeof this.data.content === 'string') {
    } else if (this.data.content instanceof TemplateRef) {
      this.portal = new TemplatePortal(this.data.content, null!, {
        $implicit: { data: this.data.data, confirmRef: this.dialogRef },
      })
    } else {
      const injector = this.createInject()
      this.portal = new ComponentPortal(this.data.content, null!, injector)
    }
  }

  createInject() {
    const providers: StaticProvider[] = [
      { provide: AD_CONFIRM_DATA, useValue: this.data.data },
      {
        provide: AD_CONFIRM_REF,
        useValue: this.dialogRef,
      },
    ]
    return Injector.create({ parent: this.injector, providers })
  }

  ngOnInit(): void {}
}
